/* Title:		
 *
 * Project:     
 *
 * @ Link: 		http://...
 *
 * @ Email:		ivan_ling@hotmail.com
 *
 * @ Copyright: Copyright (c) 2008 pub
 *
 * @ Author 	Ivan.ling
 *
 * @ Version 	1.0
 
 * @ last change time 2008-01-20 	
 */
package com.dmzapp.api.util;

import java.util.Arrays;
import java.util.HashSet;
import java.util.regex.Pattern;

public class StringUtils
{
	
	/* main method
	 * @ param 	String[] : nothing param.
	 */
	public static void main(String args[])
	{
//		System.out.println("3ff3 === " + StringUtils.strCut("中国人民解", 3, "..."));
		
		System.out.println("3ff3 === " + StringUtils.toLowerCaseForLetter("中国人民解abcBB"));
		
		//System.out.println("33333 === " + StringUtils.isContains(".*iphone.*", "iphone"));
		//System.out.println("33333 === " + StringUtils.isASCII("fdafadfadfdsfasfNinh"));
		
		//String strCache = "Bizrate.csv";
		//System.out.println("out === " + StringUtils.strCut("Excellent quality and values!  Exceptional packaging.", 30, "..."));
		//System.out.println("out === " + StringUtils.isNoCharNumMoreThanScale("abc.?,/", 50));
		
//		HashSet<Character> hsFilterChar = new HashSet<Character>();
//		hsFilterChar.add(',');
//		hsFilterChar.add('+');
//		hsFilterChar.add('$');
//		hsFilterChar.add('\"');
//		hsFilterChar.add('(');
//		hsFilterChar.add(')');
//		hsFilterChar.add('.');
//		hsFilterChar.add(':');
//		hsFilterChar.add('?');
//		hsFilterChar.add('\\');
//		hsFilterChar.add('~');
//		hsFilterChar.add(';');
//		
//		HashSet<Character> hsSpecFilterChar = new HashSet<Character>();
//		hsSpecFilterChar.add('\'');
//				
//		//System.out.println("out === " + StringUtils.isSpecFilterCharArray(StringUtils.strTripSelectCharArray("\"aphoi\" ++ . \"3g",hsFilterChar), hsSpecFilterChar));
//		
//		//System.out.println("out === " + StringUtils.isSpecFilterCharArray("\"aphoi's ++ . \"3g", hsSpecFilterChar));
//		//System.out.println("out === " + StringUtils.isTripSelectCharArray("laptops; notebooks", hsFilterChar));
//		//System.out.println("out === " + StringUtils.isLimitChars("OK", 3));
//		System.out.println("szie === " + StringUtils.strCut("abc de ccc", 5, null));
		
		//System.out.println("Delimeter count is:" + StringUtils.elementCount("ab->|:|<-cd->|:|<-efghijklmn->|:|<-opqrs->|:|<-tuvw->|:|<-xyz", "[-]{1}[>]{1}[|]{1}[:]{1}[|]{1}[<]{1}[-]{1}"));
		
		
//		System.out.println("-->" +StringUtils.getStrDelimeter("10|1069|333|444|555", "|", 1) + "<--");		
//		System.out.println("-->" +StringUtils.getStrDelimeter("10|1069|333|444|555", "|", 2) + "<--");		
//		System.out.println("-->" +StringUtils.getStrDelimeter("10|1069|333|444|555", "|", 3) + "<--");		
//		System.out.println("-->" +StringUtils.getStrDelimeter("10|1069|333|444|555", "|", 4) + "<--");		
//		System.out.println("-->" +StringUtils.getStrDeliToEnd("10|1069|333|444|555", "|", 4) + "<--");		
	}
	
	public static String toFirstLetterToUpper(String strChange)
	{
		String tempFirst 	= strChange.substring(0, 1);
		String tempElse 	= strChange.substring(1, strChange.length());
	      
	     return tempFirst.toUpperCase() + tempElse.toLowerCase();
	}
	
	public static String toLowerCase(String inputStr) {
		StringBuilder s = new StringBuilder();
		for (int i = 0; i < inputStr.length(); i++) {
			String oneStr = inputStr.substring(i, i + 1);
			if (oneStr.compareTo("A") >= 0 && oneStr.compareTo("Z") <= 0) {
				oneStr = oneStr.toLowerCase();
			}
			s.append(oneStr);
		}
		return s.toString();
	}

	public static boolean isLimitChars(String strSource, int iLimit)
  	{
  		boolean isReturn = true;
  		
  		int i, j;
  		int iSourceLen = strSource.length();
  		
  		for (i = 0; i < iSourceLen; i++) {
  			for (j = i; j < iSourceLen; j++){
				if (Character.isLowerCase(strSource.charAt(j)) || Character.isUpperCase(strSource.charAt(j))){
					continue;
				}else
					break;
			}
  			
 			if(j != 0 && (j - i ) == iLimit){
  				isReturn = false;
  				break;
  			}
  		}
  		
  		return isReturn;
  	}
   	
	public static boolean isContains(String strRegx, String strTarget)
	{
		return strTarget.matches(strRegx);
	}
	
	public static boolean isContainsAutoFormat(String strRegx, String strTarget)
	{
		return strTarget.matches(strStrConvertRegxFormat(strRegx));
	}
	
	/* beta version. not use.
    * @ param 	String 	strInput 	input string
    * @ return 	String 	
    */ 
	public static boolean isContainsBeta (String strSource, String strTarget)
	{
		int iStartIndex = strSource.indexOf("*");//--> first char
		
		if(iStartIndex == -1){
			if(strTarget.equals(Pattern.quote(strSource)))
				return true;
			else
				return false;
		}		
		
		String strCache;
		int iEndIndex, iTargetStartIndex;
		iTargetStartIndex = 0;

		while(iStartIndex != -1){
			iEndIndex = strSource.indexOf("*", iStartIndex + 1);//--> first char
			if(iEndIndex == -1){
				iEndIndex = strSource.length();
			}
			
			strCache = strSource.substring(iStartIndex + 1, iEndIndex);
			System.out.println("strCache === " +strCache);
			iTargetStartIndex = strTarget.indexOf(strCache, iTargetStartIndex);//-->
			if(iTargetStartIndex == -1){
				return false;
			}else{
				iTargetStartIndex = iTargetStartIndex + (iEndIndex - iStartIndex);
				iStartIndex = strSource.indexOf("*", iEndIndex);
			}
			
			System.out.println("iStartIndex === " +iStartIndex);
			System.out.println("iEndIndex === " +iEndIndex);
		}
		
		return true;
	}
	
	
	/* add slashes into input string.
    * @ param 	String 	strInput 	input string
    * @ return 	String 	
    */   	
   	public static String addcslashes(String strInput)
   	{
   		if(strInput == null )
   			return "";
   		return(strInput.replaceAll("\\\\'","'").replaceAll("\\\\\"","\"").replaceAll("\\\\","\\\\\\\\").replaceAll("\"","\\\\\"").replaceAll("'","\\\\'"));
	}
   	
   	public static String addSlash(String strInput)
   	{
   		if(strInput.charAt(0) == '\\')
   			strInput = "\\" + strInput;
   		if(strInput.charAt(strInput.length() - 1) == '\\')
   			strInput += "\\";
   		return strInput;
	}
   	
   	public static String mysql_escape_string(String origanl)
   	{
        char str[] = origanl.toCharArray();
        int length = str.length;
        char[] str_result = new char[2*length+1];
        int str_length = 0;
        for(int i=0,j=0;i<length;i++){
            char escape = '\0';
            switch (str[i]) {
            case '\0':            //* Must be escaped for 'mysql' 
              escape= '0';
              break;
            case '\n':            //* Must be escaped for logs 
              escape= 'n';
              break;
            case '\r':
              escape= 'r';
              break;
            case '\\':
              escape= '\\';
              break;
            case '\'':
              escape= '\'';
              break;
            case '"':             // Better safe than sorry 
              escape= '"';
              break;
            case '\032':          // This gives problems on Win32 
              escape= 'Z';
              break;
            }
            if(escape != '\0'){
               str_result[j] = '\\';
               j++;
               str_result[j] = escape;
               j++;
            }else{
               str_result[j] = str[i];
               j++;
            }
            str_length = j;
        }

        String result = "";
        for(int i=0;i<str_length;i++){
            result = result + str_result[i];
        }
               
        return result;
    }
   	
   	public static String strStrConvertRegxFormat(String strInput)
   	{
   		return strInput.replaceAll("\\*", ".*");
	}
   	
   	public static String strTripSelectChar(String strSource, char chTripChar)
   	{
   		int len = strSource.length();
 	  	StringBuffer sbTmp = new StringBuffer(len);
 	  	for(int i = 0;i < len; i++){
 	  		if(strSource.charAt(i) != chTripChar)
 	  			sbTmp.append(strSource.charAt(i));
 	  	}
 	  	return sbTmp.toString();
   	}
   	
   	public static String strTripSelectCharArray(String strSource, HashSet<Character> hsTripChar)
   	{
   		int len = strSource.length();
 	  	StringBuffer sbTmp = new StringBuffer(len);
 	  	for(int i = 0;i < len; i++){
 	  		if(!hsTripChar.contains(strSource.charAt(i)))
 	  			sbTmp.append(strSource.charAt(i));
 	  	}
 	  	return sbTmp.toString();
   	}
   	
   	public static boolean isTripSelectCharArray(String strSource, HashSet<Character> hsTripChar)
   	{
   		int len = strSource.length();
   		boolean isReturn = false;
   		
 	  	for(int i = 0;i < len; i++){
 	  		if(hsTripChar.contains(strSource.charAt(i))){
 	  			isReturn = true;
 	  			break;
 	  		}
 	  	}
 	  	
 	  	return isReturn;
   	}
   	
	public static String strSpecFilterCharArray(String strSource, HashSet<Character> hsTripChar)
   	{
   		int len = strSource.length();
   		char chSpace = ' ';
   		
 	  	StringBuffer sbTmp = new StringBuffer(len);
 	  	for(int i = 0;i < len; i++){
 	  		if(hsTripChar.contains(strSource.charAt(i)) && (i == 0 || i == len - 1) || hsTripChar.contains(strSource.charAt(i)) && strSource.charAt(i - 1) == chSpace || hsTripChar.contains(strSource.charAt(i)) && strSource.charAt(i + 1) == chSpace)
 	  			continue;
 	  		else
 	  			sbTmp.append(strSource.charAt(i));
 	  	}
 	  	
 	  	return sbTmp.toString();
   	}
   	
	public static boolean isSpecFilterCharArray(String strSource, HashSet<Character> hsTripChar)
   	{
   		int len = strSource.length();
   		char chSpace = ' ';
   		
 	  	boolean isReturn = false;
 	  	
 	  	for(int i = 0;i < len; i++){
 	  		if(hsTripChar.contains(strSource.charAt(i)) && (i == 0 || i == len - 1) || hsTripChar.contains(strSource.charAt(i)) && strSource.charAt(i - 1) == chSpace || hsTripChar.contains(strSource.charAt(i)) && strSource.charAt(i + 1) == chSpace){
 	  			isReturn = true;
 	  			break;
 	  		}else
 	  			continue;
 	  	}
 	  	
 	  	return isReturn;
   	}
	
    /* It delete into not char and number from input string.
     * @ param 	String 	strInput 	input string
     * @ return 	String
     */
    public static String fetchCharVSnumber(String strInput)
    {
    	int len = strInput.length();
 	  	StringBuffer sbTmp = new StringBuffer(len);
 	  	for(int i = 0;i < len; i++){
 	  		if(strInput.charAt(i) > 96 && strInput.charAt(i) < 123 || strInput.charAt(i) > 64 && strInput.charAt(i) < 91 || strInput.charAt(i) > 47 && strInput.charAt(i) < 58)
 	  			sbTmp.append(strInput.charAt(i));
 	  	}
 	  	return sbTmp.toString();
 	}
    
    /* It delete into not char and number from input string.
     * @ param 	String 	strInput 	input string
     * @ return 	String
     */
    public static String getKeyboardChars(String strInput)
    {
    	int len = strInput.length();
 	  	StringBuffer sbReturn = new StringBuffer(len);
 	  	
 	  	for(int i = 0;i < len; i++){
 	  		if(strInput.charAt(i) > 31 && strInput.charAt(i) < 128)
 	  			sbReturn.append(strInput.charAt(i));
 	  	}
 	  	
 	  	return sbReturn.toString();
 	}
  	
    public static int iNoCharNumScale(String strInput)
    {
    	int iNoCharNumTotal = 0;
    	
    	int iLen = strInput.length();
 	  	for(int i = 0;i < iLen; i++){
 	  		if(strInput.charAt(i) > 96 && strInput.charAt(i) < 123 || strInput.charAt(i) > 64 && strInput.charAt(i) < 91 || strInput.charAt(i) > 47 && strInput.charAt(i) < 58)
 	  			continue;
 	  		else
 	  			iNoCharNumTotal++;
 	  	}
    	
 	  	return Math.round(iNoCharNumTotal / iLen * 100);
    }
    
    public static boolean isNoCharNumMoreThanScale(String strInput, int iLimit)
    {
    	int iNoCharNumTotal = 0;
    	
    	int iLen = strInput.length();
 	  	for(int i = 0;i < iLen; i++){
  	  		if(strInput.charAt(i) > 0 && strInput.charAt(i) < 48 || strInput.charAt(i) > 57 && strInput.charAt(i) < 65 || strInput.charAt(i) > 90 && strInput.charAt(i) < 97  || strInput.charAt(i) > 122 && strInput.charAt(i) < 128)
 	  			iNoCharNumTotal++;
 	  	}
 	  	
 	  	return Math.round((float)iNoCharNumTotal / (float)iLen * 100) > iLimit;
    }
    
    public static String strCut(String strSource, int iLimit, String strAppend)
    {
    	if(strSource == null)
    		return null;
    	
    	if(strSource.length() > iLimit){
    		StringBuilder sbCache;
    		if(strAppend == null)
    			sbCache = new StringBuilder(iLimit);
    		else
    			sbCache = new StringBuilder(iLimit + strAppend.length());
    		
    		String strCache;
          		
    		if(strSource.charAt(iLimit) != ' '){
    			if(strSource.lastIndexOf(' ', iLimit) == -1)
    				strCache = strSource.substring(0, iLimit).trim();
    			else
    				strCache = strSource.substring(0, strSource.lastIndexOf(' ', iLimit)).trim();
    		}else
    			strCache = strSource.substring(0, iLimit).trim();
    		
    		int iEndPos = strCache.length();

			for(int i = strCache.length() - 1; i >= 0; i--){
				if(Character.isLetterOrDigit(strCache.charAt(i))){
					break;
				}else
					iEndPos--;
			}

			if(iEndPos != strCache.length())
				strCache = strCache.substring(0, iEndPos);
			
			sbCache.append(strCache);
			if(strAppend != null)
				sbCache.append(strAppend);
   			
   			return sbCache.toString();
    	}else
    		return strSource;
    }
    
    /*
   	public static String mysql_escape_string(String origanl)
   	{
        char str[] = origanl.toCharArray();
        int length = str.length;
        char[] str_result = new char[2*length+1];
        int str_length = 0;
        for(int i=0,j=0;i<length;i++){
            char escape = '\0';
            switch (str[i]) {
            case '\0':            //* Must be escaped for 'mysql' 
              escape= '0';
              break;
            case '\n':            //* Must be escaped for logs 
              escape= 'n';
              break;
            case '\r':
              escape= 'r';
              break;
            case '\\':
              escape= '\\';
              break;
            case '\'':
              escape= '\'';
              break;
            case '"':             //* Better safe than sorry 
              escape= '"';
              break;
            case '\032':          //* This gives problems on Win32 
              escape= 'Z';
              break;
            }
            if(escape != '\0'){
               str_result[j] = '\\';
               j++;
               str_result[j] = escape;
               j++;
            }else{
               str_result[j] = str[i];
               j++;
            }
            str_length = j;
        }

        String result = "";
        for(int i=0;i<str_length;i++){
            result = result + str_result[i];
        }
               
        return result;
    }
    */
   	
   	public static boolean isMoreThanLengthChars(String strSource, int iLimit)
   	{
        char[] cs = strSource.toCharArray();  
       
   		return cs.length > iLimit ? true : false ;
   		
   	}
   	
   	public static boolean isASCII(String strSource)
   	{
   		boolean isReturn = true;
   		
        char[] cs = strSource.toCharArray();  
        for (int i = 0; i < cs.length; i++)   {  
        	if(!(cs[i] < 128)){

				isReturn = false;
				break; 
			}  
		}
        
   		return isReturn;
   	}
   	
   	public static int[] similar_str_Full(String txt1, int len1, String txt2, int len2, int pos1, int pos2, int max)
	{
		int[] returnArr = new int[3];

		max = 0;

		for(int p=0; p<len1; p++){
			for(int q=0; q<len2; q++){
				char[] txt1_temp = txt1.substring(p).toCharArray();
				char[] txt2_temp = txt2.substring(q).toCharArray();

				int l=0;

				for(; (p+l < len1) && (q+l < len2) && (txt1_temp[l] == txt2_temp[l]) ; l++);

				if(l > max){
					max = l;
					pos1= p;
					pos2= q;

					returnArr[0] = l;
					returnArr[1] = p;
					returnArr[2] = q;
				}
			}
		}

		return returnArr;
	}

   	
	public static int similar_char_Full(String txt1, int len1, String txt2, int len2)
	{
		int pos1 = 0;
		int pos2 = 0;
		int max  = 0;
		int sum  = 0;
		int[] returnArr = new int[3];

		returnArr = similar_str_Full(txt1, len1, txt2, len2, pos1, pos2, max);

		max  = returnArr[0];
		pos1 = returnArr[1];
		pos2 = returnArr[2];

		sum = max;

		if ( sum>0 ) {
			if (pos1>0 && pos2>0)
				sum += similar_char_Full(txt1, pos1, txt2, pos2);

			if ( (pos1 + max < len1) && (pos2 + max < len2) )
				sum += similar_char_Full(txt1.substring(pos1 + max), len1 - pos1 - max, txt2.substring(pos2 + max), len2 - pos2 - max);
		}
		return sum;
	}
	
	public static int similar_Full(String t1, String t2)
	{
		int sim = similar_char_Full(t1, t1.length(), t2, t2.length());
		return sim * 200 / (t1.length() + t2.length());
	}
	
	public static String Bytes2HexString(byte[] b) {
		String ret = "";
		for (int i = 0; i < b.length; i++) {
			String hex = Integer.toHexString(b[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			ret += hex.toUpperCase();
		}
		return ret;
	}
	
	public static String Bytes2HexString(byte b) 
	{
		String hex = Integer.toHexString(b & 0xFF);
		if (hex.length() == 1) {
			hex += "0";
		}
		
		hex = hex.toUpperCase();
		return hex;
	}
	
	public static String Bytes2HexString(Byte[] b) {
		String ret = "";
		for (int i = 0; i < b.length; i++) {
			String hex = Integer.toHexString(b[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			ret += hex.toUpperCase();
		}
		return ret;
	}
	
	public static byte[] strbyte_escape(byte[] b_content){
		int j=0;
		byte[] b_content_conv = new byte[2*b_content.length];
		for (int i=0; i<b_content.length; i++){
			switch (b_content[i]){
			 case '\\':
				b_content_conv[j++] = '\\';
				b_content_conv[j++] = '\\';
	            break;
			case '\'':
				b_content_conv[j++] = '\\';
				b_content_conv[j++] = '\'';
				break;
			case '\"':
				b_content_conv[j++] = '\\';
				b_content_conv[j++] = '"';
				break;
			default :
				b_content_conv[j++] = b_content[i];
			}
		}
		return Arrays.copyOfRange(b_content_conv, 0, j);
    }
	
	/*
	 * 
	 * @param inStr
	 * @param DeliStr
	 * @param DeliStartNum
	 * @return String
	 * 
	 * For Example: a String abc|bde|efg|hik as inStr, "|" as Delistr, if 2 as DeliStartNum, the return str is  bde
	 */
	public static String getStrDelimeter(String inStr, String DeliStr, int DeliStartNum){
		int fromIndex = 0;
		int start = fromIndex;
		int end = 0;
		int DeliCnt = 0;
		while ((end = inStr.indexOf(DeliStr, fromIndex)) != -1){
			DeliCnt += 1;
			if (DeliCnt == DeliStartNum){
				break;
			}
			fromIndex = end + DeliStr.length();
			start = fromIndex;
		}
		if (start>=0 && end > 0){
			return inStr.substring(start, end);
		} else {
			return "";
		}
	}

	/*
	 * @param inStr
	 * @param DeliStr
	 * @param DeliStartNum
	 * @return String
	 * 
	 * For Example: a String abc|bde|efg|hik as inStr, "|" as Delistr, if 2 as DeliStartNum, the return str is  efg|hik
	 */
	public static String getStrDeliToEnd(String inStr, String DeliStr, int DeliStartNum){
		int fromIndex = 0;
		int start = fromIndex;
		int DeliCnt = 0;
		while ((start = inStr.indexOf(DeliStr, fromIndex)) != -1){
			DeliCnt += 1;
			if (DeliCnt == DeliStartNum){
				break;
			}
			fromIndex = start+DeliStr.length();
			//System.out.println("---: DeliCnt:" + DeliCnt + "; fromIndex:" + fromIndex + "; start:" + start);
		}
		if (start>=0){
			return inStr.substring(start+DeliStr.length());
		} else {
			return "";
		}
	}
	
	public static int elementCount(String inStr, String DeliStr) {
		int fromIndex = 0;
		int start = fromIndex;
		int DeliCnt = 0;
		while ((start = inStr.indexOf(DeliStr, fromIndex)) != -1){
			DeliCnt += 1;
			fromIndex = start+DeliStr.length();
		}

		return DeliCnt+1;
	}

	/**
    * transfer hex string to bytes.
    * @param hex
    * @return
    */
    public static byte[] hexStringToByte(String hex) {
        int len = (hex.length() / 2);
		byte[] result = new byte[len];
		char[] achar = hex.toCharArray();
		for (int i = 0; i < len; i++) {
			int pos = i * 2;
			result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
		}
		return result;
    }
    
    private static byte toByte(char c) 
    {
        byte b = (byte) "0123456789ABCDEF".indexOf(c);
        return b;
    }
    
    public static String toLowerCaseForLetter(String source)
    {
    	StringBuilder sbReturn = new StringBuilder(source.length());
    	
    	int len = source.length();
    	char ch;
    	for(int i = 0; i < len; i++){
    		ch = source.charAt(i);
    		
    		if(Character.isUpperCase(ch)){
    			sbReturn.append(Character.toLowerCase(ch));
    		}else{
    			sbReturn.append(ch);
    		}
    	}
    	
    	return sbReturn.toString();
    }
    
    public static String getNameValue(String name, String content)
	{
		name 			= "name=\"" + name + "\" value=\"";
		String value 	= "";
		
		int pos1 = content.indexOf(name);
	
	    if( pos1 != -1) {
	    	int nameLen = name.length();
	    	
	    	int pos2 = content.indexOf("\"", pos1 + nameLen);
	    	if( pos2 != -1) {
	   			value = content.substring(pos1 + nameLen, pos2);
	    	}
	    }
	
		return value;
	}
    
    public static String na2Null(String str) {
    	if ("n/a".equalsIgnoreCase(str)) {
			return null;
		} 
    	return str;
    }
    
    public static boolean isNullOrEmpty(String str) {
    	if (null == str || str.trim().equals("")) {
    		return true;
    	} else {
    		return false;
    	}
    }

}